/******************************************************************************
*
*  MP3Play Widget -- SongList
*  Created by Patrick Neeley <patrick@neeley.org>
*             http://www.neeley.org/
*  Created on 2007.08.02
*  Updated on 2007.08.03
*
*  Description:

   A class that contains and manages multiple SongEntry components.  Mostly 
   for layout and scrolling control.  Also tracks which song is being played, 
   and stops it if another song's play button is pressed.

******************************************************************************/

import flash.MovieClip;


class SongList extends Component
{
  var g_Songs : Array<SongEntry>;

  var g_ScrollPosition : Int;
  var g_MaxSongs : Int;

  static var g_EntryHeight : Int = 18;
  static var g_EntryVSpace : Int = 2;
  static var g_EntryColor : Int = 0xEFEFEF;
  static var g_EntryText : Int = 0x000000;
  static var g_ButtonSize : Int = 16;

  var g_bAllowDownload : Bool;

  var g_btnUp : Button;
  var g_btnDown : Button;
  var g_bUpOn : Bool;
  var g_bDownOn : Bool;

  var g_ScrollBar : Component;
  var g_ScrollLimit : Int;
  var g_ScrollBarStep : Float;

  public function new (root, bAllowDownload:Bool, x, y, w, h, ?color, ?entrycolor, ?entrytext) {
    super(root, false, 0);
    this.move(x,y,w,h);

    (color == null) ? this.setColor(0xAFAFEF): this.setColor(color);
    if (entrycolor != null) {
      g_EntryColor = entrycolor;
    }
    if (entrytext != null) {
      g_EntryText = entrytext;
    }

    g_bAllowDownload = bAllowDownload;

    g_Songs = new Array<SongEntry>();
    g_ScrollPosition = 0;
    g_MaxSongs = Math.floor(h / (g_EntryHeight + g_EntryVSpace));

    g_btnUp = new Button(this.mc, "upoffimg", false, (this._width - g_ButtonSize - 1), 1, g_ButtonSize, g_ButtonSize);
    g_btnDown = new Button(this.mc, "downoffimg", false, (this._width - g_ButtonSize - 1), (this._height - g_ButtonSize - 1), g_ButtonSize, g_ButtonSize);
    g_bUpOn = false;
    g_bDownOn = false;
    g_btnUp.onPress = this.ScrollUp;
    g_btnDown.onPress = this.ScrollDown;

    g_ScrollBar = new Component(this.mc, false);
    g_ScrollBar.setColor(g_EntryColor);
    g_ScrollBar.setAlpha(50);
    this.updateScrollLimit();
  }


  public function addSong (file:String, title:String, duration:String, dlfile:String) {
    if (file == "") {
      return;
    }

      // create the song and add it to the list
    var newsong = new SongEntry(
      this.mc, g_Songs.length, file, title, duration,
      dlfile, g_bAllowDownload, false,
      null, null, null, null,
      g_EntryColor, g_EntryText
    );
    newsong.onPlay = this.onPlaySongHandler;
    if (g_bAllowDownload) {
      newsong.onDownload = this.DownloadHandler;
    }
    g_Songs.push(newsong);

      // redraw the song list to make any visible, new songs appear
    this.updateScrollLimit();
    this.updatePosition(g_ScrollPosition);
  }


  private function onSelectSongHandler (num:Int, file:String, title:String) {
    this.onSelectSong(num, file, title);
  }
  public function onSelectSong (num:Int, file:String, title:String) {
    // This is just a placeholder; it must be implemented after an instance
    // of this class has been created.
  }

  private function onPlaySongHandler (num:Int, file:String, title:String, dlfile:String) {
    this.onPlaySong(num, file, title, dlfile);
  }
  public function onPlaySong (num:Int, file:String, title:String, dlfile:String) {
    // This is just a placeholder; it must be implemented after an instance
    // of this class has been created.
  }


    // this function is also in PlayStrip.hx
  private function DownloadHandler (dlfile:String) {
    if (g_bAllowDownload) {
      onDownload(dlfile);
    }
  }
  public function onDownload (dlfile:String) {
    // This is just a placeholder; it must be implemented after an instance
    // of this class has been created.
  }


  public function playNextEntry (num)
  {
    if (num > -1 && num < g_Songs.length - 1) {
      var e = g_Songs[++num];
      this.onPlaySong(e.g_num, e.g_file, e.g_title, e.g_dlfile);
    }
  }
  // end playNextEntry


  public function ScrollUp () {
    if (g_bUpOn) {
      this.updatePosition(g_ScrollPosition - 1);
    }
  }

  public function ScrollDown () {
    if (g_bDownOn) {
      this.updatePosition(g_ScrollPosition + 1);
    }
  }

  private function updateScrollLimit ()
  {
    g_ScrollLimit = 0;
    var TH = this._height - 36;
    var BH = TH;
    var BHP : Float = 1.0;
    g_ScrollBarStep = 0.0;

    if (g_Songs.length > g_MaxSongs) {
      g_ScrollLimit = g_Songs.length - g_MaxSongs;
      BHP = (g_MaxSongs / g_Songs.length);
      BH = Math.floor(TH * BHP);
      if (g_ScrollLimit > 0) {
        g_ScrollBarStep = (TH - BH) / g_ScrollLimit;
      }
    }
    var y = 18 + (g_ScrollBarStep * g_ScrollPosition);
    g_ScrollBar.move(this._width - 17, y, 16, BH);
  }

  public function updatePosition (newpos:Int)
  {
      // make sure the position is within the valid range
    if (newpos < 0) {
      newpos = 0;
    }
    else if (newpos > g_ScrollLimit) {
      newpos = g_ScrollLimit;
    }
    g_ScrollPosition = newpos;

      // make invisible all songs that are out of range, and position the
      // others properly
    var i;
    for (i in 0 ... g_Songs.length) {
      if (i >= newpos && i < newpos + g_MaxSongs) {
        var y :Int = 2 + ((i - newpos) * (g_EntryHeight + g_EntryVSpace));
        g_Songs[i].move(2, y, this._width - (2*g_EntryVSpace) - 18, g_EntryHeight);
        g_Songs[i].setVisible(true);
      } else {
        g_Songs[i].setVisible(false);
      }
    }

      // re-display the scrolling controls
    if (g_bUpOn && newpos == 0) {
      g_btnUp.setDisplay("upoffimg", false);
      g_bUpOn = false;
    }
    else if (!g_bUpOn && newpos > 0) {
      g_btnUp.setDisplay("uponimg", false);
      g_bUpOn = true;
    }
    if (g_bDownOn && newpos == g_ScrollLimit) {
      g_btnDown.setDisplay("downoffimg", false);
      g_bDownOn = false;
    }
    else if (!g_bDownOn && newpos < g_ScrollLimit) {
      g_btnDown.setDisplay("downonimg", false);
      g_bDownOn = true;
    }

    g_ScrollBar.setY(18 + (g_ScrollBarStep * newpos));
  }
  // end updatePosition


  public function setEntryColors (color, text)
  {
    if (color == null && text == null) {
      return;
    }
    if (color != null) {
      g_EntryColor = color;
      g_ScrollBar.setColor(color);
    }
    if (text != null) {
      g_EntryText = text;
    }
    for (i in 0 ... g_Songs.length) {
      if (color != null) {
        g_Songs[i].setColor(color);
      }
      if (text != null) {
        g_Songs[i].setTextColor(text);
      }
    }
  }
  // end setEntryColors


  public function destroy ()
  {
    if (g_btnUp != null) {
      g_btnUp.destroy();
    }
    if (g_btnDown != null) {
      g_btnDown.destroy();
    }
    if (g_ScrollBar != null) {
      g_ScrollBar.destroy();
    }
    if (g_Songs != null) {
      for (song in g_Songs) {
        song.destroy();
      }
    }
    super.destroy();
  }
  // end function destroy

}
// end class SongList
